package com.xiaomaoguai.fcp.pre.kepler.router.handler.handlers;

import com.xiaomaoguai.fcp.pre.kepler.router.buf.Buf;
import com.xiaomaoguai.fcp.pre.kepler.router.handler.RouterInfo;
import com.xiaomaoguai.fcp.pre.kepler.router.handler.api.BatchHandler;
import com.xiaomaoguai.fcp.pre.kepler.router.handler.api.HandlerContext;
import com.xiaomaoguai.fcp.pre.kepler.router.router.RouterPipeline;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.List;


public abstract class AbstractBatchHandler<I> extends AbstractHandler<I> implements BatchHandler<I> {

	protected Logger log = LoggerFactory.getLogger(this.getClass());

	@Override
	public void handle(HandlerContext<I> hc) {
		List<I> readList;
		long length = getExecuteNum(hc);
		for (int i = 0; i < length; i++) {
			readList = read(hc, i);
			before(hc, readList);
			write(hc, readList);
			after(hc, readList);
			for (I one : readList) {
				b2oInvoke(hc, one);
			}
		}
		complete(hc);
	}

	@Override
	public List<I> read(HandlerContext<I> hc, int offset) {
		return null;
	}

	@Override
	public I convert(String s) {
		return null;
	}

	@Override
	public void before(HandlerContext<I> hc, List<I> list) {

	}

	@Override
	public void write(HandlerContext<I> hc, List<I> list) {

	}

	@Override
	public void after(HandlerContext<I> hc, List<I> list) {

	}

	@Override
	public void complete(HandlerContext<I> hc) {

	}

	public abstract long getPageSize(HandlerContext<I> hc);

	public abstract long getExecuteNum(HandlerContext<I> hc);

	public abstract Buf convert2Buf(Object o);

	@Override
	public boolean b2oInvoke(HandlerContext<I> hc, Object o) {
		Buf buf = convert2Buf(o);
		// 深拷贝新的pipe
		RouterPipeline<?, ?> routerPipeline = hc.getRouter().clone().setBuf(buf);
		return runRouterPipeline(hc, routerPipeline);
	}

	protected boolean runRouterPipeline(HandlerContext<I> hc, RouterPipeline<?, ?> routerPipeline) {
		// 有分支处理时且为GOTO ADD_PIPELINE TERMINATED 直接continue
		RouterInfo routerInfo = hc.getRouterInfo();
		return routerPipeline.branchInvoke(routerInfo);
	}

	@Override
	public boolean isB2O() {
		return Boolean.TRUE;
	}
}
